package com.project.utils;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.project.utils.file.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

/**
 * @author : Mr.Yan
 * @program : com.project.utils
 * @create : 2020/07/16
 * @description : ftp下载资源线程
 */
@Slf4j
public class FtpDownLoadUtils {

    public void download(FTPClient ftpClient, String remote, String name, HttpServletRequest request) throws IOException {
        String ftpRemote = remote + "/" + name;
        String sessionName = name;
        // 设置被动模式
        ftpClient.enterLocalPassiveMode();
        // 设置以二进制方式传输
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        FTPFile[] ftpFiles = ftpClient.listFiles(ftpRemote);  // 判断文件存在
        if (ftpFiles.length != 1) {
            log.warn("文件不存在");
            return ;
        }
        // 需下载文件的大小
        long remoteSize = ftpFiles[0].getSize();
        File[] roots = File.listRoots();
        String path = roots[roots.length - 1].getPath();
        // 定义文件存储位置
        String local = path + "\\ftpdownload";
        File localFileDirs = new File(local);
        // 本地文件路径不存在创建目录
        if (!localFileDirs.exists()) {
            localFileDirs.mkdirs();
        }
        // 本地文件
        File localFile = new File(local, name);
        // 存在但是没有下载完成需要继续下载
        // 本地文件下载了多少
        long localSize = localFile.length();
        // 本地文件比需要的大则表示下载完成了
        if (localSize >= remoteSize) {
            String prefix = FileUtil.getExtensionName(name);
            name = String.format("%s-%s-%s.%s", StrUtil.sub(name, 0 , ((prefix.length() + 1) * -1 )), DateUtil.format(new Date(), "yyyyMMdd"), String.valueOf(System.currentTimeMillis()), prefix);
            // 重新创建一个文件
            localFile = new File(local, name);
            localSize = localFile.length();
        }
        // 进行从多少字节开始读取 断点续传，并记录状态
        FileOutputStream out = new FileOutputStream(localFile, true);
        // 找出本地已经接收了多少
        ftpClient.setRestartOffset(localSize);
        // 读取需下载文件
        InputStream in = ftpClient.retrieveFileStream(ftpRemote);
        // 设置每次读取1024字节
        byte[] b = new byte[1024];
        int i = 0;
        // 进度
        long step = ((remoteSize / 100) == 0 ? 1 :  remoteSize / 100); // 多少个100
        long process = localSize / step; // 设置下载进度
        // 判断读取字节数
        while ( (i = in.read(b)) != -1 ) {
            // 写入输出流
            out.write(b,0, i);
            // 设置本地的文件存储字节
            localSize += i;
            if (remoteSize > 1024) {
                // 设置进度
                long nowProcess = localSize / step ;
                if (nowProcess > process) {
                    process = nowProcess;
                    if (process % 10 == 0) { // 以10 为单位进行下载
                        log.info("已经下载:" + process);
                        // 设置进度条进度
                        request.getSession().setAttribute("process" + sessionName, process);
                    }
                }
            } else {
                process = 100;
                log.info("已经下载: 100" );
                request.getSession().setAttribute("process" + sessionName, process);
            }
        }
        // 关闭流
        out.close();
        in.close();
    }

}
